home *** CD-ROM | disk | FTP | other *** search
/ The Best of MacTutor - S…e Code for Volumes 1 to 5 / The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin / Source Code / #13 (Oct 86) / c source / printw.c < prev    next >
C/C++ Source or Header  |  1986-09-09  |  12KB  |  518 lines

  1. /* Sending text to window with
  2.  *  function that accepts a variable
  3.  *    number of parameters
  4.  *
  5.  * Compiled with LightspeedC
  6.  *
  7.  *    Important note for Mac C users:
  8.  *    Every place you see event->where,
  9.  *    replace it with &event->where
  10.  */
  11.  
  12.  
  13.  #include    "abc.h"
  14.  #include    "Quickdraw.h"
  15.  #include    "EventMgr.h"
  16.  #include    "WindowMgr.h"
  17.  #include    "MenuMgr.h"
  18.  
  19.  /* defines for menu ID's */
  20.  
  21.  #define        Mdesk        100
  22.  #define        Mfile        101
  23.  #define        Medit        102
  24.  #define        Mwind        103
  25.  #define        Mtest        104
  26.  
  27.  /* Global variables */
  28.  
  29.  MenuHandle        menuDesk;    /* menu handles */
  30.  MenuHandle        menuFile;
  31.  MenuHandle        menuEdit;
  32.  MenuHandle        menuWind;
  33.  MenuHandle        menuTest;
  34.  
  35.  
  36.  WindowPtr            theWindow;
  37.  WindowRecord        windowRec;
  38.  Rect                dragbound;
  39.  Rect                limitRect;
  40.  
  41. main()
  42. {
  43.     initsys();        /* system initialization */
  44.     initapp();        /* application initialization */
  45.     eventloop();
  46. }
  47.  
  48. /* system initialization 
  49.  *        note use of hard coded screen sizes
  50.  *        with LightspeedC.  This will work
  51.  *        with other compilers but is not
  52.  *        good practice
  53.  */
  54. initsys()        
  55. {                    
  56.     InitGraf(&thePort);    /* these two lines done */
  57.     InitFonts();            /* automatically by Mac C */
  58.     InitWindows();
  59.     InitCursor();
  60.     InitMenus();
  61.     theWindow = Nil;        /*indicates no window */
  62.     SetRect(&dragbound,0,0,512,250);
  63.     SetRect(&limitRect,60,40,508,244);
  64. }
  65.  
  66. /*
  67.  *    application initialization
  68.  *        Sets up menus.
  69.  *        Each menu is a separate group
  70.  *        of lines.  Note the last menu
  71.  *        is appended but not inserted.  This
  72.  *        makes it part of the menu list but 
  73.  *        not in the menu bar.
  74.  */
  75. initapp()
  76. {
  77.     menuDesk = NewMenu(Mdesk,CtoPstr("\24"));
  78.     AddResMenu (menuDesk, 'DRVR');
  79.     InsertMenu (menuDesk, 0);
  80.     
  81.     menuFile = NewMenu(Mfile, CtoPstr("File"));
  82.     AppendMenu (menuFile, 
  83.         CtoPstr("Open Window/M;Close Window/X;Quit/Q"));
  84.     AppendMenu (menuFile, 
  85.         CtoPstr("(-;Show Test;(Hide Test"));
  86.     InsertMenu (menuFile, 0);
  87.     
  88.     menuEdit = NewMenu(Medit, CtoPstr("Edit"));
  89.     AppendMenu (menuEdit, 
  90.         CtoPstr("Undo;(-;Cut;Copy;Paste;Clear"));
  91.     InsertMenu (menuEdit, 0);
  92.     
  93.     menuWind = NewMenu(Mwind, CtoPstr("Window"));
  94.     AppendMenu (menuWind, 
  95.         CtoPstr("Hide;Show;New Title"));
  96.     InsertMenu (menuWind, 0);
  97.     
  98.     menuTest = NewMenu(Mtest, CtoPstr("Test"));
  99.     AppendMenu (menuTest, 
  100.         CtoPstr("Pick;One;Of;These"));
  101.     
  102.     DrawMenuBar();
  103. }
  104.     
  105. /*    Event Loop 
  106.  *        Loop forever until Quit
  107.  */
  108. eventloop()
  109. {
  110.     EventRecord    theEvent;
  111.     char            c;
  112.     short            windowcode;
  113.     WindowPtr        ww;
  114.     
  115.     while(True)
  116.         {
  117.         if (theWindow)            /* this code is here to prevent */
  118.             {                /* closing an already closed */
  119.             EnableItem(menuFile,2);    /* window! */
  120.             DisableItem(menuFile,1);
  121.             }
  122.         else                            
  123.             {                        
  124.             EnableItem(menuFile,1);
  125.             DisableItem(menuFile,2);
  126.             }
  127.             
  128.         if (GetNextEvent(everyEvent,&theEvent))
  129.             switch(theEvent.what)    
  130.                 {                    /* only check key and */
  131.                 case keyDown:     /* mouse down events */
  132.                     if (theEvent.modifiers & cmdKey)
  133.                         {
  134.                         c = theEvent.message &                             charCodeMask;
  135.                         domenu(MenuKey(c));
  136.                         }
  137.                     break;
  138.                 case mouseDown:
  139.                     domouse(&theEvent);
  140.                     break;
  141.                 default:
  142.                     break;
  143.                 }
  144.         }
  145. }
  146.  
  147.  
  148. /* domouse
  149.  *        handle mouse down events
  150.  */
  151. domouse(er)
  152.     EventRecord    *er;
  153. {
  154.     short            windowcode;
  155.     WindowPtr        whichWindow;
  156.     short            ingo;
  157.     long            size;
  158.     ushort            t1 = 0xFFFF;
  159.     short            t2 = 0xFFFF;
  160.     
  161.     windowcode = FindWindow(er->where, &whichWindow);
  162.     switch (windowcode)
  163.         {
  164.         case inDesk:
  165.             if (theWindow notequal 0)
  166.                 {
  167.                 HiliteWindow(theWindow, False);
  168.                 DrawGrowIcon(theWindow);
  169.                 }
  170.             printw(" In Desk %d %ld %d ",10,123L,-456);
  171.             break;
  172.         case inMenuBar:
  173.             printw("\nIn MenuBar %u %d ",t2,t1);
  174.             domenu(MenuSelect(er->where));
  175.             break;
  176.         case inSysWindow:
  177.             SysBeep(1);
  178.             break;
  179.         case inContent:
  180.             printw("\nIn content %ld %d",700000,700000);
  181.             if (whichWindow equals theWindow)
  182.                 {
  183.                 HiliteWindow(whichWindow,True);
  184.                 DrawGrowIcon(theWindow);
  185.                 }
  186.             break;
  187.         case inDrag:
  188.             DragWindow(whichWindow, er->where, &dragbound);
  189.             DrawGrowIcon(theWindow);
  190.             break;
  191.         case inGrow:
  192.             /* not included this month */
  193.             break;
  194.         case inGoAway:
  195.             ingo = TrackGoAway(whichWindow,er->where);
  196.             if (ingo)
  197.                 {
  198.                 CloseWindow(whichWindow);
  199.                 theWindow = Nil;
  200.                 }
  201.             break;
  202.         }
  203. }
  204.  
  205. /* domenu
  206.  *        handles menu activity
  207.  *        simply a dispatcher for each
  208.  *        menu.
  209.  */
  210. domenu(mc)
  211.     long            mc;    /* menu result */
  212. {
  213.     short            menuId;
  214.     short            menuitem;
  215.     
  216.     menuId = HiWord(mc);
  217.     menuitem = LoWord(mc);
  218.     
  219.     switch (menuId)
  220.         {
  221.         case Mdesk  : 
  222.             break;    /* not handling DA's */
  223.         case Mfile  : 
  224.             dofile(menuitem);
  225.             break;
  226.         case Medit  : 
  227.             break;
  228.         case Mwind : 
  229.             dowind(menuitem);
  230.              break;
  231.         case Mtest : 
  232.             dotest(menuitem);
  233.             break;
  234.         }
  235.     HiliteMenu(0);
  236. }
  237.  
  238. /* dofile
  239.  *        handles file menu
  240.  */
  241. dofile(item)
  242.     short        item;
  243. {
  244.     char        *title1;            /* first title for window */
  245.     Rect        boundsRect;
  246.     
  247.     switch (item)
  248.         {
  249.         case 1 :        /* open the window */
  250.             title1 = "ABC Window";
  251.             SetRect(&boundsRect,50,50,300,150);
  252.             theWindow = NewWindow(&windowRec,                         &boundsRect,
  253.                                                     CtoPstr(title1),True,documentProc,
  254.                             (WindowPtr) -1, True, 0);
  255.             DrawGrowIcon(theWindow);
  256.             PtoCstr(title1);
  257.             DisableItem(menuFile,1);
  258.             EnableItem(menuFile,2);
  259.             break;
  260.         
  261.         case 2 :        /* close the window */
  262.             CloseWindow(theWindow);
  263.             theWindow = Nil;
  264.             DisableItem(menuFile,2);
  265.             EnableItem(menuFile,1);
  266.             break;
  267.         
  268.         case 3 :        /* Quit */
  269.             ExitToShell();
  270.             break;
  271.             
  272.         case 5 :        /* Install additional menu */
  273.             InsertMenu(menuTest,0);
  274.             EnableItem(menuFile,6);
  275.             DisableItem(menuFile,5);
  276.             DrawMenuBar();
  277.             break;
  278.             
  279.         case 6 :        /* remove additional menu */
  280.             DeleteMenu(Mtest);
  281.             EnableItem(menuFile,5);
  282.             DisableItem(menuFile,6);
  283.             DrawMenuBar();
  284.             break;
  285.         }
  286. }
  287.  
  288. /*
  289.  *    dowind
  290.  *        handles window menu 
  291.  *        Note that each case contains an
  292.  *        if testing the existance of the
  293.  *        window.  This could be written
  294.  *        with one if before the switch.
  295.  */
  296. dowind(item)
  297.     short        item;
  298. {
  299.     char        *title2;            /* second title for window */
  300.     
  301.     switch (item)
  302.         {
  303.         case 1 :    /* Hide */
  304.             if (theWindow)
  305.                 HideWindow(theWindow);
  306.             break;
  307.         case 2 :    /* Show */
  308.             if (theWindow)
  309.                 ShowWindow(theWindow);
  310.             break;
  311.         case 3 :    /* Change title */
  312.             if (theWindow)
  313.                 {
  314.                 title2 = "A Different Title";
  315.                 SetWTitle(theWindow, CtoPstr(title2));
  316.                 PtoCstr(title2);
  317.                 }
  318.             break;
  319.         }
  320. }
  321.  
  322. /*    dotest
  323.  *        Handles new menu.
  324.  *        All this does is mark menu
  325.  *        items if they are not marked and
  326.  *         unmark them if they are.
  327.  */
  328. dotest(item)
  329.     short        item;
  330. {
  331.     short        mark;
  332.     
  333.     GetItemMark(menuTest,item,&mark);
  334.     if (mark)
  335.         CheckItem(menuTest,item,False);
  336.     else
  337.         CheckItem(menuTest,item,True);
  338. }
  339.  
  340. /* Displays strings and numbers in a 
  341.  * special window
  342.  *        This function is designed to receive
  343.  *        a variable number of parameters. The 
  344.  *        number is computed by the number of
  345.  *        percent signs in the control string.
  346.  *        If the number of parameters following the 
  347.  *        control string does not match the 
  348.  *        number of percent signs, expect 
  349.  *        the unexpected.
  350.  */
  351. printw(s)
  352.     char        *s;        /* the control string */
  353. {
  354. #define    Bufsz    14        /* size of buffer to hold */
  355.                         /* converted numbers */    
  356.  
  357. static Rect            boundsRect;    /* variables for */
  358. static Rect            windowRect;    /* defining printw */
  359. static WindowRecord    wrc;        /* window, pw is */
  360. static WindowPtr    pw = 0;            /* initialized to 0 */
  361. WindowPtr            oldport;        /* save grafport here */
  362. short                linesz;            /* size of line */
  363. FontInfo                info;            
  364. short                nl;
  365. Point                pt;
  366. RgnHandle            updrgn;        /* needed for scrolling */
  367. char                numAsStr[Bufsz];    /* number conversion */
  368. short                nsz;        /* size of numbers (2 or 4) */
  369. char                    **ts;            /* ptr to ptr to ctrl string */
  370. char                    *ps;            /* ptr to parameters */
  371. ulong                num;            /* for number conversion */
  372. short                convchar;        /* found conversion char */
  373. short                islong;            /* number is a long */
  374.     
  375. /* Window rectancgle coordinates */
  376.  
  377. #define    wl        0
  378. #define    wr        512
  379. #define    wt        250
  380. #define    wb        342
  381.     
  382.     
  383. GetPort(&oldport);                /* save current graph port */
  384. GetFontInfo(&info);                /* compute line height */
  385. linesz = info.ascent + info.descent;
  386. if (pw equals 0)                    /* if window does not exist*/
  387.     {                            /*  open it */
  388.         SetRect(&boundsRect,wl,wt,wr,wb);
  389.         pw = NewWindow(&wrc, &boundsRect,
  390.                     CtoPstr(""),True,plainDBox,
  391.                     (WindowPtr) -1, True, 0);
  392.         nl = linesz;                /* move down one line as */
  393.     }                            /*  writing will be above */
  394.     else                        /*  boundary.  No need to  */
  395.         nl = 0;                    /*  move line if  open */
  396.     SetPort(pw);                /* Set port to this window */
  397.     Move(0,nl);                /* Move (relative) */
  398.     
  399.     ts = &s;            /* get address of control string ptr */
  400.     ps = (char *)ts;    /* convert to pointer to params */
  401.     ps += sizeof(long);    /* skip over control string pointer*/
  402.     while (*s)                /* loop until end of control string */
  403.         {
  404.         switch (*s)            /* check each character */
  405.             {
  406.             case '%' :    /* percent sign: check conversion */
  407.                 s++;        /* point to next char */
  408.                 convchar = False;        /* initialize conv  loop */
  409.                 islong = False;
  410.                 do {            /*  until reach conv char */
  411.                     switch (*s)
  412.                         {
  413.                         case 'l' :        /* indicates a long */
  414.                             islong = True;
  415.                             s++;
  416.                             break;
  417.                         case 'u'    :    /* unsigned decimal */
  418.                         case 'd'     :    /* signed decimal */
  419.                             if (islong)    /* extract number  */
  420.                                 {
  421.                                 num = *(ulong*)ps;
  422.                                 nsz = sizeof(long);
  423.                                 }
  424.                             else
  425.                                 {
  426.                                 num = *(ushort*)ps;
  427.                                 nsz = sizeof(short);
  428.                                 }
  429.                             ps += nsz;    /* point to next param */
  430.                             /* convert number and write it to 
  431.                              *   window
  432.                              */
  433.                             ntoa(num,nsz,'u' - *s,numAsStr);
  434.                             DrawString(CtoPstr(numAsStr));
  435.                             convchar = True;
  436.                             break;
  437.                         /* strings, individual chars and hex                          * numbers not handled yet
  438.                         */
  439.                         case 's'   :
  440.                             break;    
  441.                         case 'c'    :
  442.                             break;
  443.                         /* if it is not any expected char,
  444.                          * write it out and go on
  445.                          */
  446.                         default    :   
  447.                             DrawChar(*s);
  448.                             convchar = True;
  449.                         } 
  450.                     } while (not convchar);
  451.                 break;
  452.             case '\n' :        /* newline ('\n') in control string */
  453.                 GetPen(&pt);    /* find current pen position */
  454.                 if (pt.v+linesz > wb-wt)   /* if it goes off , */
  455.                     {                /* scroll the window */
  456.                     updrgn = NewRgn();
  457.                     ScrollRect(&(pw->portRect),0,-linesz,updrgn);
  458.                     DisposeRgn(updrgn);  /* no update */
  459.                     Move(0,-linesz);    /* move onto window */
  460.                     }
  461.                 Move(-pt.h,linesz);/* move to next line */                break;
  462.             default :            /* any other character gets */
  463.                 DrawChar(*s);    /*  written on the window */
  464.             }
  465.         s++;                    /* move pointer to next char */
  466.         }                        /*  in control string and cont*/
  467.     SetPort(oldport);            /* restore orignal graf port */
  468. }
  469.  
  470. /*    Convert numbers to ascii strings
  471.  *        Handles signed and unsigned
  472.  *        short and long values
  473.  *    Note:    Length of string returned 
  474.  *            must be large enough to 
  475.  *            hold -2G (12 bytes)
  476.  */
  477. ntoa(n,len,issigned,s)
  478.     ulong            n;            /* number to convert */
  479.     short            len;        /* size of n (2 or 4)*/
  480.     short            issigned;    /* signed flag */
  481.     char            *s;            /* string to return */
  482. {
  483.     char             ts[12];        /* temporary string */
  484.     int                 i = 0;        /* counter, initialized */
  485.     ulong            m;            /* working copy of */
  486.     long            sm;        /* to convert signed values */
  487.     
  488.     if (n equals 0)         /* if n is zero, place '0' */
  489.         ts[i++] = '0';    /*  in temporary string */
  490.     else
  491.         {
  492.         if (issigned)        /* if sign flag is set, */
  493.             {                /*  convert to signed value */
  494.             if (len equals sizeof(long))
  495.                 sm = (long)n;
  496.             else
  497.                 sm = (short)n;
  498.             if (issigned = sm < 0)    /* Check if value is */
  499.                 n = -sm;                /*  negative. If so, */
  500.             }                            /*  keep the flag and */
  501.                                 /*  get the absolute value */
  502.         while (n)            /* Convert number into ascii */
  503.             {                /*  by repeatedly taking mod */
  504.             ts[i++] = n % 10 + '0';    /*  and dividing.  */
  505.             n /= 10;                /*  This gives a string in */
  506.             }                        /*  reverse order */
  507.         if (issigned)            /* If number was negative, */
  508.             ts[i++] = '-';            /*  stick a minus sign in */
  509.         }                            /*  the string.*/
  510.                 
  511.     do    {                            /* Reverse the string */
  512.         *s++ = ts[--i];        /*  to the correct direction*/
  513.         }    
  514.     while (i);
  515.  
  516.     *s = '\0';                /* Place null terminator on */
  517. }                                /*  string */
  518.